﻿using System;
using System.Collections.Generic;

namespace mqtttLib.Helper
{
    public class DoubleKey<TK1, TK2, TV>
    {
        public DoubleKey(TK1 k1, TK2 k2, TV v)
        {
            K1 = k1;
            K2 = k2;
            V = v;
        }

        public TK1 K1 { get; set; }
        public TK2 K2 { get; set; }
        public TV V { get; set; }
    }

    /// <summary> 
    /// 自定义键值对 
    /// </summary> 
    /// <typeparam name="TK1">键</typeparam> 
    /// <typeparam name="TK2">值</typeparam> 
    /// <typeparam name="TV">值</typeparam>

    [Serializable]
    public class DoubleKeyDictionary<TK1, TK2, TV>
    {


        // cline id
        // 地址
        public int Count;
        /// <summary>
        /// 键
        /// </summary>
        public Dictionary<TK1, DoubleKey<TK1, TK2, TV>> Values1 = new Dictionary<TK1, DoubleKey<TK1, TK2, TV>>();
        /// <summary>
        /// 值
        /// </summary>
        public Dictionary<TK2, DoubleKey<TK1, TK2, TV>> Values2 = new Dictionary<TK2, DoubleKey<TK1, TK2, TV>>();

        object lockobject = new object();

        /// <summary> 
        /// 添加 
        /// </summary> 
        /// <param name="k1">键</param> 
        /// <param name="k2">值</param> 
        /// <param name="v">值</param>

        public void Add(TK1 k1, TK2 k2, TV v)
        {
            lock (lockobject)
            {


                var model = new DoubleKey<TK1, TK2, TV>(k1, k2, v);
                Values1.Add(k1, model);
                Values2.Add(k2, model);
                Count++;
            }

        }

        public TV Get(TK1 k1)
        {
            if (Values1.ContainsKey(k1))
            {
                return Values1[k1].V;
            }
            return default(TV);
        }
        public TV Get(TK2 k2)
        {
            if (Values2.ContainsKey(k2))
            {
                return Values2[k2].V;
            }
            return default(TV);
        }
        public TK1 GetK(TK2 k2)
        {
            if (Values2.ContainsKey(k2))
            {
                return Values2[k2].K1;
            }
            return default(TK1);
        }
        public TK2 GetK(TK1 k1)
        {
            if (Values1.ContainsKey(k1))
            {
                return Values1[k1].K2;
            }
            return default(TK2);
        }

        public bool ContainsKey(TK1 k1)
        {
            return (Values1.ContainsKey(k1));

        }
        public bool ContainsKey(TK2 k2)
        {
            return (Values2.ContainsKey(k2));
        }

        public bool Remove(TK1 k1)
        {
            if (Values1.ContainsKey(k1))
            {
                if (Values2.ContainsKey(Values1[k1].K2))
                {
                    if (Values2.Remove(Values1[k1].K2))
                    {
                        if (Values1.Remove(k1))
                        {
                            Count--;
                            return true;
                        }
                    }
                }
                // return !Values2.ContainsKey(Values1[k1].K2) || Values2.Remove(Values1[k1].K2);
            }
            return true;
        }
        public bool Remove(TK2 k2)
        {
            if (Values2.ContainsKey(k2))
            {
                if (Values1.ContainsKey(Values2[k2].K1))
                {
                    if (Values1.Remove(Values2[k2].K1))
                    {
                        if (Values2.Remove(k2))
                        {
                            Count--;
                            return true;
                        }
                    }
                }
            }
            return true;
        }



    }

}